package com.aiti.lulian.workflow;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.baomidou.mybatisplus.annotation.TableName;


import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@TableName("dj_task_instance")
public class TaskInstance {
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private String id;

    private String processInstanceId;

    private String taskDefinitionId;

    private String name;


    private TaskType type;


    private AssigneeType assigneeType;

    private String assigneeId;

    private Date startTime;

    private Date endTime;


    private TaskStatus status;

    private String rejectToNodeId;


    private String variablesJson;

    @JsonIgnore
    @TableField(exist = false)
    private Map<String, Object> variables;

    @JsonIgnore
    @TableField(exist = false)
    private ProcessInstance processInstance;

    public TaskInstance() {
        this.status = TaskStatus.PENDING;
        this.startTime = new Date();
        this.variables = new HashMap<>();
        this.type = TaskType.NORMAL;
    }

    public void complete(Map<String, Object> variables, String comment) {
        this.status = TaskStatus.COMPLETED;
        this.endTime = new Date();
        if (variables != null) {
            this.variables.putAll(variables);
            this.variablesJson = convertVariablesToJson();
        }
    }

    public void cancel() {
        this.status = TaskStatus.CANCELLED;
        this.endTime = new Date();
    }

    private String convertVariablesToJson() {
        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(variables);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("转换错误", e);
        }
    }

    private Map<String, Object> convertJsonToVariables(String json) {
        try {
            if (json == null || json.trim().isEmpty()) {
                return new HashMap<>();
            }
            ObjectMapper mapper = new ObjectMapper();
            return mapper.readValue(json, new TypeReference<Map<String, Object>>() {});
        } catch (Exception e) {
            throw new RuntimeException("转换错误", e);
        }
    }

    // Getters and Setters
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public String getProcessInstanceId() { return processInstanceId; }
    public void setProcessInstanceId(String processInstanceId) { this.processInstanceId = processInstanceId; }

    public String getTaskDefinitionId() { return taskDefinitionId; }
    public void setTaskDefinitionId(String taskDefinitionId) { this.taskDefinitionId = taskDefinitionId; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public TaskType getType() { return type; }
    public void setType(TaskType type) { this.type = type; }

    public AssigneeType getAssigneeType() { return assigneeType; }
    public void setAssigneeType(AssigneeType assigneeType) { this.assigneeType = assigneeType; }

    public String getAssigneeId() { return assigneeId; }
    public void setAssigneeId(String assigneeId) { this.assigneeId = assigneeId; }

    public Date getStartTime() { return startTime; }
    public void setStartTime(Date startTime) { this.startTime = startTime; }

    public Date getEndTime() { return endTime; }
    public void setEndTime(Date endTime) { this.endTime = endTime; }

    public TaskStatus getStatus() { return status; }
    public void setStatus(TaskStatus status) { this.status = status; }

    public String getRejectToNodeId() { return rejectToNodeId; }
    public void setRejectToNodeId(String rejectToNodeId) { this.rejectToNodeId = rejectToNodeId; }

    public String getVariablesJson() { return variablesJson; }
    public void setVariablesJson(String variablesJson) {
        this.variablesJson = variablesJson;
        this.variables = convertJsonToVariables(variablesJson);
    }

    @JsonIgnore
    public Map<String, Object> getVariables() {
        if (variables == null && variablesJson != null) {
            variables = convertJsonToVariables(variablesJson);
        }
        return variables != null ? new HashMap<>(variables) : new HashMap<>();
    }

    public void setVariables(Map<String, Object> variables) {
        this.variables = variables != null ? new HashMap<>(variables) : new HashMap<>();
        this.variablesJson = convertVariablesToJson();
    }

    @JsonIgnore
    public ProcessInstance getProcessInstance() { return processInstance; }
    public void setProcessInstance(ProcessInstance processInstance) { this.processInstance = processInstance; }

    @Override
    public String toString() {
        return "TaskInstance{" +
                "id='" + id + '\'' +
                ", processInstanceId='" + processInstanceId + '\'' +
                ", taskDefinitionId='" + taskDefinitionId + '\'' +
                ", name='" + name + '\'' +
                ", status=" + status +
                ", startTime=" + startTime +
                ", endTime=" + endTime +
                '}';
    }
}
